package tech.aistar.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tech.aistar.dto.AgentGrade;
import tech.aistar.dto.HeSearch;
import tech.aistar.entity.House;
import tech.aistar.mapper.AgentMapper;
import tech.aistar.mapper.HouseMapper;
import tech.aistar.service.IES;

import javax.transaction.Transactional;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Transactional
public class ES implements IES {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Autowired
    private HouseMapper houseMapper;
    @Autowired
    private AgentMapper agentMapper;

    //    向Es中添加索引
    @Override
    public String  addEsIndex() {
        return null;
    }

    @Override
    public String delEsIndex() {
        return null;
    }


    //合租
        @Override
        public String addEsDoc(){

            List<House> house=houseMapper.selectHe();
            BulkRequest bulkRequest=new BulkRequest();
            bulkRequest.timeout("2m");
            for (int i = 0; i <house.size() ; i++) {
                bulkRequest.add(
                        new IndexRequest("house_he")
                                .id(""+(i+1))
                                .source(JSON.toJSONString(house.get(i)), XContentType.JSON));
            }
            BulkResponse bulkItemResponses= null;
            try {
                bulkItemResponses = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if(!bulkItemResponses.hasFailures()){
                return "添加文档成功";
            }else {
                return "添加文档失败";
            }
        }

    @Override
    public String addEsAgent() {
        List<AgentGrade> agentGradeList=agentMapper.selectAgent();
        BulkRequest bulkRequest=new BulkRequest();
        bulkRequest.timeout("2m");
        for (int i = 0; i <agentGradeList.size() ; i++) {
            bulkRequest.add(
                    new IndexRequest("agent_grade")
                            .id(""+(i+1))
                            .source(JSON.toJSONString(agentGradeList.get(i)), XContentType.JSON));
        }
        BulkResponse bulkItemResponses= null;
        try {
            bulkItemResponses = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if(!bulkItemResponses.hasFailures()){
            return "添加文档成功";
        }else {
            return "添加文档失败";
        }
    }

    @Override
    public List<Map<String, Object>> searchEsAgent(String content) {
        SearchRequest searchRequest = new SearchRequest("agent_grade");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询条件
        MatchQueryBuilder termQueryBuilder = QueryBuilders.matchQuery("name", content);

        sourceBuilder.query(termQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

        //高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name");//
        highlightBuilder.requireFieldMatch(false);//多个高亮显示
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
        sourceBuilder.highlighter(highlightBuilder);

        //执行搜索
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = null;
        try {
            searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //解析结果
        List<Map<String,Object>> list=new ArrayList<>();
        for (SearchHit hit : searchResponse.getHits().getHits()) {

            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField name = highlightFields.get("name");
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            //解析高亮字段
            if (name!=null){
                Text[] fragments = name.fragments();
                String names = "";
                for (Text text : fragments) {
                    names += text;
                }
                sourceAsMap.put("name",names);//高亮字段替换原来的内容即可
            }
            list.add(sourceAsMap);

        }
        return list;
    }

    //整租
    @Override
    public String addEsDocZheng(){

        List<House> house=houseMapper.selectZheng();
        BulkRequest bulkRequest=new BulkRequest();
        bulkRequest.timeout("2m");
        for (int i = 0; i <house.size() ; i++) {
            bulkRequest.add(
                    new IndexRequest("house_zheng")
                            .id(""+(i+1))
                            .source(JSON.toJSONString(house.get(i)), XContentType.JSON));
        }
        BulkResponse bulkItemResponses= null;
        try {
            bulkItemResponses = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if(!bulkItemResponses.hasFailures()){
            return "添加文档成功";
        }else {
            return "添加文档失败";
        }
    }




    @Override
    public String findDoc() {
        return null;
    }

    //合租
    @Override
    public List<Map<String, Object>> searchEs(String content) {
        SearchRequest searchRequest = new SearchRequest("house_he");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询条件
        MatchQueryBuilder termQueryBuilder = QueryBuilders.matchQuery("residentialQuarters", content);

        sourceBuilder.query(termQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

        //高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("residentialQuarters");//
        highlightBuilder.requireFieldMatch(false);//多个高亮显示
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
        sourceBuilder.highlighter(highlightBuilder);

        //执行搜索
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = null;
        try {
            searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //解析结果
        List<Map<String,Object>> list=new ArrayList<>();
        for (SearchHit hit : searchResponse.getHits().getHits()) {

            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField residentialQuarters = highlightFields.get("residentialQuarters");
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            //解析高亮字段
            if (residentialQuarters!=null){
                Text[] fragments = residentialQuarters.fragments();
                String name = "";
                for (Text text : fragments) {
                    name += text;
                }
                sourceAsMap.put("residentialQuarters",name);//高亮字段替换原来的内容即可
            }
            list.add(sourceAsMap);

        }
        return list;
    }

    @Override
    public PageInfo<HeSearch> heESPage(String sea, Integer pageNow, Integer pageSize) {
        PageHelper.startPage(pageNow,pageSize);

        List<Map<String, Object>> houses = searchEs(sea);
            List<HeSearch> list = new ArrayList<>();
        HeSearch heSearch = new HeSearch();
        for (Map<String, Object> map :houses) {

            heSearch.setId((Integer) map.get("id"));
            heSearch.setDoorplate(map.get("doorplate").toString());
            heSearch.setResidentialQuarters(map.get("residentialQuarters").toString());
            heSearch.setImageUrl(map.get("imageUrl").toString());
            heSearch.setRentMoney((Double) map.get("rentMoney"));
            heSearch.setOrientate(map.get("orientate").toString());
            heSearch.setRegion(map.get("region").toString());
            heSearch.setHouseType(map.get("houseType").toString());
            heSearch.setArea(map.get("area").toString());
        list.add(heSearch);
    }
        PageInfo<HeSearch> housePageInfo = new PageInfo<>(list);
//        System.out.println(housePageInfo);
        return housePageInfo;
    }

    @Override
    public PageInfo<HeSearch> zhengESPage(String sea, Integer pageNow, Integer pageSize) {
        PageHelper.startPage(pageNow,pageSize);

        List<Map<String, Object>> houses = searchEs(sea);
        List<HeSearch> list = new ArrayList<>();
        HeSearch heSearch = new HeSearch();
        for (Map<String, Object> map :houses) {

            heSearch.setId((Integer) map.get("id"));
            heSearch.setDoorplate(map.get("doorplate").toString());
            heSearch.setResidentialQuarters(map.get("residentialQuarters").toString());
            heSearch.setImageUrl(map.get("imageUrl").toString());
            heSearch.setRentMoney((Double) map.get("rentMoney"));
            heSearch.setOrientate(map.get("orientate").toString());
            heSearch.setRegion(map.get("region").toString());
            heSearch.setHouseType(map.get("houseType").toString());
            heSearch.setArea(map.get("area").toString());
            list.add(heSearch);
        }
        PageInfo<HeSearch> housePageInfo = new PageInfo<>(list);
//        System.out.println(housePageInfo);
        return housePageInfo;
    }


    //整租
    @Override
    public List<Map<String, Object>> searchEsZheng(String content) {
        SearchRequest searchRequest = new SearchRequest("house_zheng");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询条件
        MatchQueryBuilder termQueryBuilder = QueryBuilders.matchQuery("residentialQuarters", content);

        sourceBuilder.query(termQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

        //高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("residentialQuarters");//
        highlightBuilder.requireFieldMatch(false);//多个高亮显示
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
        sourceBuilder.highlighter(highlightBuilder);

        //执行搜索
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = null;
        try {
            searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //解析结果
        List<Map<String,Object>> list=new ArrayList<>();
        for (SearchHit hit : searchResponse.getHits().getHits()) {

            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField residentialQuarters = highlightFields.get("residentialQuarters");
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            //解析高亮字段
            if (residentialQuarters!=null){
                Text[] fragments = residentialQuarters.fragments();
                String name = "";
                for (Text text : fragments) {
                    name += text;
                }
                sourceAsMap.put("residentialQuarters",name);//高亮字段替换原来的内容即可
            }
            list.add(sourceAsMap);

        }
        return list;
    }

    //普通搜索无高亮显示--合租
    @Override
    public List<Map<String, Object>> searchESPT(String content) {
        SearchRequest searchRequest = new SearchRequest("house");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询条件
        MatchQueryBuilder termQueryBuilder = QueryBuilders.matchQuery("houseEvaluate", content);

        sourceBuilder.query(termQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

        //执行搜索
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = null;
        try {
            searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //解析结果
        List<Map<String,Object>> list=new ArrayList<>();
        for (SearchHit hit : searchResponse.getHits().getHits()) {

            list.add(hit.getSourceAsMap());

        }
        return list;
    }

    //普通搜索无高亮显示--整租
    @Override
    public List<Map<String, Object>> searchESPTZheng(String content) {
        SearchRequest searchRequest = new SearchRequest("house");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询条件
        MatchQueryBuilder termQueryBuilder = QueryBuilders.matchQuery("houseEvaluate", content);

        sourceBuilder.query(termQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

        //执行搜索
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = null;
        try {
            searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //解析结果
        List<Map<String,Object>> list=new ArrayList<>();
        for (SearchHit hit : searchResponse.getHits().getHits()) {

            list.add(hit.getSourceAsMap());

        }
        return list;
    }


}